function [bestmatch,matchscore,diff0,diff1] = matchtypes(action1,action0,price,pricethreshold,models)

% This function takes the actions conditional on good and bad signals and
% matches them to risk-neutral, risk-averse, risk-seeking, and PT types. It
% returns the best match where a match on either action scores 0.5 and a
% mismatch scores 0. The matchsccore is normalized by the number of
% observations.

% models is a bit map controlling which models to include
%   1 - risk-neutral only
%   2 - all expected utility
%   3 - prospect theory, no loss aversion
%   4 - prospect theory, with loss aversion
%   5 - symmetric model only (best fit with only symmetry as a constraint)

% for the full prospect theory model it also returns the
% cutoff thresholds at which transitions occur in terms of the difference
% in good and bad signals;

nobs = size(price,1);

rn_action1 = ones(nobs,1);
rn_action0 = -1*ones(nobs,1);
bestmatch = -1;
matchscore = -1;
    
if models(1) ==1    % risk-neutral
    rn_score = sum(0.5*(action1==rn_action1)) + sum(0.5*(action0==rn_action0));
    matchscore = rn_score;
    bestmatch = 0;
end

if models(2) == 1 % expected utility
    % risk-averse; cutoff levels of alpha are determined in searchrisk.m
    % alpha that gives no trade
    for i=7:9 %1:9 for CARA
        ra_action1 = rn_action1.*(price<pricethreshold(i));
        ra_action0 = rn_action0.*(price>(100-pricethreshold(i)));
        ra_score = sum(0.5*(action1==ra_action1)) + sum(0.5*(action0==ra_action0));

        if ra_score > matchscore
            bestmatch = str2double(strcat('1',num2str(i)));
            matchscore = ra_score;
        end
    end

    for i=7:9 % 6:9 for CARA
        % risk-seeking: alpha that gives contrarian
        rs_action1 = rn_action1.*(price<pricethreshold(i))-rn_action1.*(price>=pricethreshold(i));
        rs_action0 = rn_action0.*(price>(100-pricethreshold(i)))-rn_action0.*(price<=(100-pricethreshold(i)));
        rs_score = sum(0.5*(action1==rs_action1)) + sum(0.5*(action0==rs_action0));

        if rs_score > matchscore
            bestmatch = str2double(strcat('2',num2str(i)));
            matchscore = rs_score;
        end
    end
end

if models(3) == 1    % prospect theory without loss aversion

    % in this case, behavior is characterized by a single transition from
    % sell to buy if herding and from buy to sell if contrarian

    % prospect theory generating herding
    % i represents price threshold
    % i=1 corresponds to good signal buying at all prices
    % i=4 corresponds to herding starting at second public signal which is
    % earliest possible given parameter restrictions
    for i=1:4 % sell to buy
        pt_action1 = rn_action0.*(price<pricethreshold(i)-0.01) + rn_action1.*(price>=pricethreshold(i)-0.01);
        pt_action0 = rn_action1.*(price>pricethreshold(10-i)+0.01) + rn_action0.*(price<=pricethreshold(10-i)+0.01);
        pt_score = sum(0.5*(action1==pt_action1)) + sum(0.5*(action0==pt_action0));

        if pt_score > matchscore
           bestmatch = str2double(strcat('100',num2str(i)));
           matchscore = pt_score;
        end
    end

    % prospect theory generating contrarian
    % in this case, signal=0 guy is same as signal=1 guy in herd case
    for i=1:5
        pt_action1 = rn_action0.*(price>pricethreshold(10-i)+0.01) + rn_action1.*(price<=pricethreshold(10-i)+0.01);
        pt_action0 = rn_action1.*(price<pricethreshold(i)-0.01) + rn_action0.*(price>=pricethreshold(i)-0.01);
        pt_score = sum(0.5*(action1==pt_action1)) + sum(0.5*(action0==pt_action0));

        if pt_score > matchscore
            bestmatch = str2double(strcat('200',num2str(i)));
            matchscore = pt_score;
        end
    end
end

if models(4) == 1 % full prospect theory
    
    % need to add thresholds at ends to handle no trade at all prices
    pricethreshold = [0 pricethreshold 100];

    % herding case
    % two transitions : for positive signal, from sell to no trade (p0) and
    % no trade to buy (p1) where 1-p0>p1
    
    % i and j represent price thresholds so need to add 1 to get index
    for i=1:4 % sell to no trade (ends at 4 because herding is not possible after a single public signal)
        idxi = i+1;
        for j=i:9-i % no trade to buy (maximum j determined by sum of differences having to be negative to ensure parameters exist)
            idxj = j+1;
            pt_action1 = rn_action0.*(price<pricethreshold(idxi)-0.01) + rn_action1.*(price>=pricethreshold(idxj)-0.01);
            pt_action0 = rn_action1.*(price>pricethreshold(12-idxi)+0.01) + rn_action0.*(price<=pricethreshold(12-idxj)+0.01);
            pt_score = sum(0.5*(action1==pt_action1)) + sum(0.5*(action0==pt_action0));

            if pt_score > matchscore
                bestmatch = str2double(strcat('10',num2str(i),num2str(j)));
                % difference between number of good and bad signals at
                % transition
                % transition is set at highest possible
                diff0 = i-5; % e.g. i=4 implies s=1 transitions to sell between -2 and -1 so set at -1
                diff1 = j-5; % e.g. j=7 implies s=1 transitions to buy between 1 and 2 so set at 2
                matchscore = pt_score;
            end
        end
    end

    % prospect theory generating contrarian
    % identical to herding case where behavior is swapped: s=0 type matches
    % behavior of s=1 type in herding case and conversely
    for i=1:5
        idxi = i+1;
        for j=i:11-i
            idxj = j+1;
            pt_action1 = rn_action0.*(price>pricethreshold(12-idxi)+0.01) + rn_action1.*(price<=pricethreshold(12-idxj)+0.01);
            pt_action0 = rn_action1.*(price<pricethreshold(idxi)-0.01) + rn_action0.*(price>=pricethreshold(idxj)-0.01);
            pt_score = sum(0.5*(action1==pt_action1)) + sum(0.5*(action0==pt_action0));

            if pt_score > matchscore
                bestmatch = str2double(strcat('20',num2str(i),num2str(j)));
                % difference between number of good and bad signals at
                % transition
                % transition is set at highest possible
                diff0 = 6-i; % e.g. i=4 implies s=1 transitions to sell between 1 and 2 so set at 2
                diff1 = 6-j; % e.g. j=7 implies s=1 transitions to buy between -2 and -1 so set at -1
                matchscore = pt_score;
            end
        end
    end
end

if models(5)==1 % symmetric model
    % this is the least restrictive model - find the action that best
    % matches observations at a given price 
    symscore = 0;
    for p = 5:9 % prices
        if p>5 % need to match for both signals
            maxs = 2;
        else
            maxs = 1; % only match for one signal since other is redundant
        end
        for s = 1:maxs % signals
            % extract actions at price and symmetric price
            if s==1 
                actionh = action1(price>pricethreshold(p)-0.01 & price < pricethreshold(p) + 0.01);
                actionl = action0(price>pricethreshold(10-p)-0.01 & price < pricethreshold(10-p) + 0.01);
            else
                actionh = action0(price>pricethreshold(p)-0.01 & price < pricethreshold(p) + 0.01);
                actionl = action1(price>pricethreshold(10-p)-0.01 & price < pricethreshold(10-p) + 0.01);
            end
            numph = size(actionh,1);
            numpl = size(actionl,1);
            tempscore(1) = sum(0.5*(ones(numph,1)==actionh)) + sum(0.5*(-1*ones(numpl,1)==actionl)); % buy
            tempscore(2) = sum(0.5*(zeros(numph,1)==actionh)) + sum(0.5*(zeros(numpl,1)==actionl)); %no trade
            tempscore(3) = sum(0.5*(-1*ones(numph,1)==actionh)) + sum(0.5*(ones(numpl,1)==actionl)); % sell
            symscore = symscore + max(tempscore);
        end
    end
    
    if symscore > matchscore
                bestmatch = 3000;
                matchscore = symscore;
    end                 
end

matchscore = matchscore/nobs;